package com.crawler.utils

import java.io._
import java.util.Date

import com.crawler.comm.{CrawlerConfig, CrawlerStorageException}
import com.crawler.service.PersistMessage
import org.json4s.DefaultFormats
import org.json4s.native.Json
import org.slf4j.LoggerFactory

/**
  * Created by tongtao.zhu on 2016/12/1.
  */
class FileUtils(val dir: String, val crawlerConfig: CrawlerConfig) {
  val log = LoggerFactory.getLogger(this.getClass)
  val filedir = new File(dir)
  createAndValidateLogDirs(filedir)
  val file = createFile()

  private def createFile() = {

  }

  private def lockDataFile(file: File): FileLock ={
    val lock = new FileLock(file)
    if(!lock.tryLock())
      throw new CrawlerStorageException("Failed to acquire lock on file .lock in " + lock.file.getParentFile.getAbsolutePath +
        ". A crawler instance in another process or thread is using this directory.")
    lock
  }

  private def createAndValidateLogDirs(dir: File) = {
    if(!dir.exists) {
      log.info("Log directory '" + dir.getAbsolutePath + "' not found, creating it.")
      val created = dir.mkdirs()
      if(!created)
        throw new CrawlerStorageException("Failed to create data file " + dir.getAbsolutePath)
    }
    if(!dir.isDirectory || !dir.canRead || !dir.canWrite)
      throw new CrawlerStorageException(dir.getAbsolutePath + " is not a readable file and writeable file.")
  }

  private def getLastFile(dir: File): File = {
    val files = dir.listFiles()
    if (files.length == 0){
      return null
    }
    var lastFile: File = files(0)
    for (file <- files){
      if (file.lastModified() > lastFile.lastModified()){
        lastFile = file
      }
    }
    lastFile
  }

  def crawlerDataStore(msg: PersistMessage) ={
    var file = getLastFile(filedir)
    if (file == null || file.length()> crawlerConfig.maxFileSize){
      file = new File(filedir,(new Date()).getTime.toString)
    }
    write(Json(DefaultFormats).write(msg)+"\n",file)
    log.info("pagesource store ...")
  }

  def write(page:String,file:File): Unit ={
    try {
      val bufferedWriter: BufferedWriter = new BufferedWriter(new FileWriter(file,true))
      bufferedWriter.write(page)
      bufferedWriter.close
    }
    catch {
      case e: IOException => {
        e.printStackTrace
      }
    }
  }
}

